package com.fox.errorcode;

import java.util.ArrayList;
import java.util.List;


/**
 * @author wujie
 * @createTime: [2019/6/21 8:34]
 * @despretion 批量自动编码打印, 请自建枚举类, 将输出导入进去
 */
public class ErrorCodePrint {
    private String serviceCode;
    private String moduleCode;
    private List<String> codes = new ArrayList<>();

    //检测输入是否超过bit值
    public static void checkBit(int bit, int num) {
        double max = Math.pow(2, bit);
        if (num < max && num >= 0)
            return;
        throw new RuntimeException(String.format("输入%d错误,输入请在 [%d,%.0f) 区间", num, 0, max));
    }

    //移位获取2进制字符串
    private static String getBinary(int bit, int num) {
        checkBit(bit, num);
        StringBuilder sb = new StringBuilder();
        for (int i = bit - 1; i >= 0; i--) {
            sb.append(num >>> i & 1);
        }
        return sb.toString();
    }

    public ErrorCodePrint setService(ErrorCodePrintConfig.s服务码 service, ErrorCodePrintConfig.f服务标志码 flag) {
        serviceCode = getBinary(12, service.getValue()) + getBinary(4, flag.getValue());
        codes.add(String.format("\n\n/**\n*服务码[%s : %s]\n*服务标志码[%s : %s]\n*/",
                service.name(), getBinary(12, service.getValue()), flag.name(), getBinary(4, flag.getValue())));
        //设置完服务要重新设置模块
        moduleCode = null;
        return this;
    }

    //链式 设置模块
    public ErrorCodePrint setModule(ErrorCodePrintConfig.m模块码 module) {
        moduleCode = getBinary(4, module.getValue1()) + getBinary(4, module.getValue2());
        codes.add(String.format("\n// 模块码[%s : %s %s]", module.name()
                , getBinary(4, module.getValue1()), getBinary(4, module.getValue2())));
        return this;
    }

    //链式 添加
    public ErrorCodePrint add(String msg, int code) {
        //最后8位
        String codeStr = getBinary(8, code);

        long val = Long.valueOf(serviceCode + moduleCode + codeStr, 2);
        String hex = String.format("0x%8s", Long.toHexString(val)).replace(" ", "0");
        String codeLine = String.format("%s(\"%s\",\"%s\"),", msg, hex, msg,codeStr);
        codes.add(codeLine);
        return this;
    }


    //输出代码到控制台
    public void printCode() {
        if (moduleCode == null)
            throw new RuntimeException("模块不能为空");
        StringBuilder codeText = new StringBuilder();
        for (String line : codes) {

            codeText.append(line + "\n");

        }

        System.out.println(codeText.substring(0,codeText.lastIndexOf(","))+";");
    }
}
